package com.yeskery.nut.bean.condition;

import com.yeskery.nut.annotation.condition.ConditionalOnApplicationType;
import com.yeskery.nut.application.ApplicationType;
import com.yeskery.nut.application.NutApplication;
import com.yeskery.nut.scan.BeanAnnotationScanMetadata;

import java.util.Arrays;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * 应用类型条件判断
 * @author sunjay
 * 2023/9/6
 */
public class OnApplicationTypeCondition implements Condition {

    /** 日志对象 */
    private static final Logger logger = Logger.getLogger(OnApplicationTypeCondition.class.getName());

    @Override
    public boolean matches(NutApplication nutApplication, Collection<BeanAnnotationScanMetadata> beanAnnotationScanMetadata, Object conditionalAnnotation) {
        ConditionalOnApplicationType conditionalOnApplicationType = (ConditionalOnApplicationType) conditionalAnnotation;
        for (ApplicationType applicationType : conditionalOnApplicationType.value()) {
            if (doMatches(nutApplication, applicationType)) {
                return true;
            }
        }
        if (logger.isLoggable(Level.FINEST)) {
            logger.log(Level.FINEST, "ApplicationType Condition Not Match, Condition[" + this.getClass().getName()
                    + "], Expect ApplicationType[" + Arrays.stream(conditionalOnApplicationType.value()).map(ApplicationType::name).collect(Collectors.joining(", "))
                    + "], Actual ApplicationType[" + nutApplication.getApplicationMetadata().getApplicationType().name() + "]");
        }
        return false;
    }

    /**
     * 判断bean是否匹配的方法
     * @param nutApplication Nut应用对象
     * @param applicationType 应用类型
     * @return bean是否匹配的方法
     */
    protected boolean doMatches (NutApplication nutApplication, ApplicationType applicationType) {
        return nutApplication.getApplicationMetadata().getApplicationType() == applicationType;
    }
}
